// 灰度发布中间件

const grayConfig = require('../../../config/gray-release');
const { logger } = require('../../../config/monitoring');
const crypto = require('crypto');

class GrayReleaseManager {
  constructor() {
    this.config = grayConfig;
    this.grayUsers = new Set();
    this.loadGrayUsers();
  }

  // 加载灰度用户
  async loadGrayUsers() {
    try {
      // 从数据库或缓存加载已确定的灰度用户
      // const users = await GrayUser.findAll();
      // users.forEach(user => this.grayUsers.add(user.userId));
      
      logger.info('Gray users loaded', { count: this.grayUsers.size });
    } catch (error) {
      logger.error('Failed to load gray users:', error);
    }
  }

  // 判断用户是否为灰度用户
  isGrayUser(userId, userInfo = {}) {
    // 检查白名单
    if (this.config.whitelist.enabled) {
      if (this.config.whitelist.users.includes(userId.toString())) {
        return true;
      }
      
      if (userInfo.phone && this.config.whitelist.phones.includes(userInfo.phone)) {
        return true;
      }
      
      if (userInfo.openid && this.config.whitelist.openids.includes(userInfo.openid)) {
        return true;
      }
    }

    // 检查已确定的灰度用户
    if (this.grayUsers.has(userId)) {
      return true;
    }

    // 按百分比策略
    if (this.config.strategy.type === 'percentage') {
      const hash = crypto.createHash('md5').update(userId.toString()).digest('hex');
      const hashValue = parseInt(hash.substring(0, 8), 16);
      const percentage = (hashValue % 100) + 1;
      
      const isGray = percentage <= this.config.strategy.percentage;
      
      if (isGray) {
        this.grayUsers.add(userId);
        this.saveGrayUser(userId, userInfo);
      }
      
      return isGray;
    }

    // 地区策略
    if (this.config.regions.enabled && userInfo.region) {
      if (this.config.regions.allowed.length > 0) {
        return this.config.regions.allowed.includes(userInfo.region);
      }
      
      if (this.config.regions.blocked.length > 0) {
        return !this.config.regions.blocked.includes(userInfo.region);
      }
    }

    return false;
  }

  // 保存灰度用户
  async saveGrayUser(userId, userInfo) {
    try {
      // 保存到数据库
      // await GrayUser.create({
      //   userId,
      //   userInfo: JSON.stringify(userInfo),
      //   createdAt: new Date()
      // });
      
      logger.info('Gray user saved', { userId });
    } catch (error) {
      logger.error('Failed to save gray user:', error);
    }
  }

  // 检查功能是否对用户开放
  isFeatureEnabled(featureName, userId, userInfo = {}) {
    const feature = this.config.features[featureName];
    
    if (!feature || !feature.enabled) {
      return false;
    }

    // 如果是灰度用户，检查功能百分比
    if (this.isGrayUser(userId, userInfo)) {
      if (feature.percentage === 100) {
        return true;
      }
      
      const hash = crypto.createHash('md5').update(`${featureName}_${userId}`).digest('hex');
      const hashValue = parseInt(hash.substring(0, 8), 16);
      const percentage = (hashValue % 100) + 1;
      
      return percentage <= feature.percentage;
    }

    return false;
  }

  // 记录用户行为
  async recordUserBehavior(userId, action, data = {}) {
    if (!this.config.dataCollection.enabled) {
      return;
    }

    try {
      const behaviorData = {
        userId,
        action,
        data,
        isGrayUser: this.grayUsers.has(userId),
        timestamp: new Date(),
        userAgent: data.userAgent,
        ip: data.ip
      };

      // 保存到数据库或发送到分析服务
      // await UserBehavior.create(behaviorData);
      
      logger.info('User behavior recorded', behaviorData);
    } catch (error) {
      logger.error('Failed to record user behavior:', error);
    }
  }

  // 获取灰度发布统计
  async getGrayReleaseStats() {
    try {
      const stats = {
        totalGrayUsers: this.grayUsers.size,
        strategy: this.config.strategy,
        features: {},
        metrics: {}
      };

      // 统计各功能的使用情况
      for (const [featureName, feature] of Object.entries(this.config.features)) {
        if (feature.enabled) {
          // 从数据库查询功能使用统计
          stats.features[featureName] = {
            enabled: feature.enabled,
            percentage: feature.percentage,
            users: 0, // 实际使用用户数
            errors: 0, // 错误数
            feedback: 0 // 反馈数
          };
        }
      }

      return stats;
    } catch (error) {
      logger.error('Failed to get gray release stats:', error);
      return null;
    }
  }
}

// 创建全局实例
const grayReleaseManager = new GrayReleaseManager();

// 灰度发布中间件
const grayReleaseMiddleware = (req, res, next) => {
  // 添加灰度发布相关方法到请求对象
  req.grayRelease = {
    isGrayUser: (userId, userInfo) => grayReleaseManager.isGrayUser(userId, userInfo),
    isFeatureEnabled: (featureName, userId, userInfo) => 
      grayReleaseManager.isFeatureEnabled(featureName, userId, userInfo),
    recordBehavior: (userId, action, data) => 
      grayReleaseManager.recordUserBehavior(userId, action, { ...data, ip: req.ip, userAgent: req.get('User-Agent') })
  };

  next();
};

// 功能开关中间件
const featureToggle = (featureName) => {
  return (req, res, next) => {
    const userId = req.user?.id;
    const userInfo = req.user;

    if (!userId) {
      return res.status(401).json({
        success: false,
        code: 401,
        message: '用户未登录'
      });
    }

    if (!grayReleaseManager.isFeatureEnabled(featureName, userId, userInfo)) {
      return res.status(403).json({
        success: false,
        code: 403,
        message: '功能暂未开放'
      });
    }

    // 记录功能使用
    grayReleaseManager.recordUserBehavior(userId, `feature_${featureName}`, {
      featureName,
      path: req.path,
      method: req.method
    });

    next();
  };
};

module.exports = {
  grayReleaseManager,
  grayReleaseMiddleware,
  featureToggle
};